/******************** (C) COPYRIGHT 2018 merafour ********************
* Author             : 冷月追风@merafour.blog.163.com
* Version            : V1.0.0
* Date               : 8/1/2019
* Description        : buffer 操作, 为避免内存泄漏请使用 new 创建对象.
********************************************************************************
* merafour.blog.163.com
* merafour@163.com
* github.com/Merafour
*******************************************************************************/
#ifndef QIQUEUE_H
#define QIQUEUE_H

//#include <QObject>
#include <stdint.h>
#include <string.h>
#include <QMutex>
//class QiQueue : public QObject
//{
//    Q_OBJECT
//public:
//    explicit QiQueue(QObject *parent = nullptr);

//signals:

//public slots:

//public:
class QiQueue
{
public:
    QiQueue()
    {
        reset();
    }
    void reset(void)
    {
        mutex.lock();
        head = 0;
        tail = 0;
        lenght = 0;
        memset(buf, 0, sizeof(buf));
        mutex.unlock();
    }
    void put_array(const char* datas, const int len)
    {
        int count=0;
        uint32_t next = 0;
        mutex.lock();
        for(count=0; count<len; count++)
        {
            //put(static_cast<uint8_t>(datas[count]));
            next = (head + 1) % sizeof(buf);
            if (next != tail) {
                buf[head] = static_cast<uint8_t>(datas[count]);
                head = next;
                lenght++;
            }
        }
        mutex.unlock();
    }
    void put(uint8_t b)
    {
        uint32_t next = 0;
        mutex.lock();
        next = (head + 1) % sizeof(buf);
        if (next != tail) {
            buf[head] = b;
            head = next;
            lenght++;
        }
        mutex.unlock();
    }

    int get(void)
    {
        int	ret = -1;
        mutex.lock();
        if (tail != head) {
            ret = buf[tail];
            tail = (tail + 1) % sizeof(buf);
            lenght--;
        }
        mutex.unlock();

        return ret;
    }
    int is_empty(void)
    {
        int	ret = -1;
        mutex.lock();
        ret = (tail == head);
        mutex.unlock();
        return ret;
    }
    int is_full(void)
    {
        int	ret = -1;
        uint32_t next = 0;
        mutex.lock();
        next = (head + 1) % sizeof(buf);
        ret = (tail == next);
        mutex.unlock();
        return ret;
    }
    uint32_t size(void)
    {
        return lenght;
    }

private:
    uint8_t buf[4096];
    uint32_t head=0, tail=0;
    uint32_t lenght;
    QMutex mutex;
};

#endif // QIQUEUE_H
